/*******************************************************************************
 * Simple C-K Editor
 * 
 * Copyright (C) 2009 Ingi BROWN - Centre de Gestion Scientifique - Ecole des Mines ParisTech
 * Licensed under the GNU General Public License Version 3.
 * 
 * Simple C-K Editor includes source code and libraries from the JUNG Project (Java Universal Network/Graph Framework) 
 * released under the BSD license. Copyright (c) 2003-2004,  Regents of the University of California and the JUNG Project.
 * 
 * See the License.txt file for more details.
 ******************************************************************************/

package edu.ensmp.ckEditor.gui;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.Collection;
import java.util.Scanner;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import edu.ensmp.ckEditor.ckModel.CKModel;
import edu.ensmp.ckEditor.ckModel.CKModel.Concept;
import edu.ensmp.ckEditor.ckModel.CKModel.Edge;
import edu.ensmp.ckEditor.ckModel.CKModel.Knowledge;
import edu.ensmp.ckEditor.main.Launcher;
import edu.ensmp.ckEditor.mousePlugin.EditingGraphMousePlugin;
import edu.ensmp.ckEditor.util.Constants;
import edu.ensmp.ckEditor.util.StringMethods;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.visualization.VisualizationViewer;


@SuppressWarnings("serial")
public class MenuBar extends JMenuBar implements ActionListener{
	
	final private JMenuItem savePNGItem;
	final private JMenuItem saveGraphItem;
	final private JMenuItem loadGraphItem;
	final private JMenuItem close;
	final private JMenuItem createGraphCK;
	final private JMenuItem actionHelp;
	final private JFrame frameCreateGraphCK = new JFrame();
	final private JPanel panelCreateGraphCK = new JPanel();
	final private JPanel panelActionHelp = new JPanel();
	
	public MenuBar() {

		JMenu actionMenu = new JMenu("File");
		JMenu help = new JMenu("Help");

		/*
		 * Save to file
		 */
		saveGraphItem = new JMenuItem("Save graph");
		actionMenu.add(saveGraphItem);
		
		/*
		 * Load a file
		 */
		loadGraphItem = new JMenuItem("Load graph");
		actionMenu.add(loadGraphItem);
		
		actionMenu.addSeparator();
		
		/*
		 * Save to PNG Item
		 */
		savePNGItem = new JMenuItem("Export to PNG image");
		actionMenu.add(savePNGItem);
		
		actionMenu.addSeparator();
		
		close = new JMenuItem("Quit "+Constants.APP_NAME);
		actionMenu.add(close);
		
		
		/*
		 * Explication sur la création d'un arbre C-K
		 */
		createGraphCK = new JMenuItem("How to create a CK Graph");
		help.add(createGraphCK);
		
		/*
		 * Explication sur les différente action du menu action
		 */
		actionHelp = new JMenuItem("Help on saving and exporting");
		help.add(actionHelp);
		
		

		frameCreateGraphCK.setTitle("Aide");
		frameCreateGraphCK.setLocation(200,300);
		frameCreateGraphCK.setSize(890, 130);
		
		JTextArea textCreateGraphCK = new JTextArea("- Créer un noeud : Pour créér un noeud, " +
													"tapez une proposition puis double-cliquez " +
													"dans la partie ou vous souhaitez le voir apparaitre " + System.getProperty("line.separator") +
													"- Créer un lien : Pour créer un lien, " +
													"double-cliquez sur le noeud de départ, " +
													"puis cliquez sur le noeud d'arrivé " + System.getProperty("line.separator") +
													"- Modifier un noeud/lien : Pour modifier un noeud/lien, " +
													"il faut effectuer un clique droit dessus " + System.getProperty("line.separator") +
													"- Déplacer un noeud : Pour déplacer un noeud, " +
													"il faut appuyer sur la touche 'p' puis, cliquer sur le noeud que l'on veut déplacer. " +
													"Appuyer ensuite sur la touche 't' ou créez un nouveau noeud pour revenir au mode de création,",5,10);
		textCreateGraphCK.setLineWrap(true);
		textCreateGraphCK.setEditable(false);
		JScrollPane scrollPane = new JScrollPane(textCreateGraphCK, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
		        JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		panelCreateGraphCK.setLayout(new BorderLayout());
		panelCreateGraphCK.add(scrollPane, BorderLayout.CENTER);
		
		
		JTextArea textActionHelp = new JTextArea("Exporter en image : Permet d'effectuer une sauvegarde en image " +
													"de l'arbre C-K " + System.getProperty("line.separator") +
													"Enregistrer le graphe : Permet d'enregistrer le travail effectuer, " +
													"sous forme de fichier de sauvegarde " + System.getProperty("line.separator") +
													"Charger un graphe : Permet de charger un fichier de sauvegarde, " +
													"pour continuer son travail",5,10);
		textActionHelp.setLineWrap(true);
		textActionHelp.setEditable(false);
		JScrollPane scrollPane2 = new JScrollPane(textActionHelp, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
		JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		panelActionHelp.setLayout(new BorderLayout());
		panelActionHelp.add(scrollPane2, BorderLayout.CENTER);

		// Add the menu to the container
		add(actionMenu);
		add(help);
		
		// Add the action listeners
		savePNGItem.addActionListener(this);
		saveGraphItem.addActionListener(this);
		loadGraphItem.addActionListener(this);
		createGraphCK.addActionListener(this);
		actionHelp.addActionListener(this);
		close.addActionListener(this);

	}

	public void actionPerformed(ActionEvent event) {
		if(event.getSource() == close){
			System.exit(0);
		}
		
		if (event.getSource() == savePNGItem) {
				
				JFileChooser fc = new JFileChooser();
				File file;
				
				try {
					
					BufferedImage image = new BufferedImage(Launcher.getEditorGUI().getSplitPane().getWidth() + 1, Launcher.getEditorGUI().getSplitPane().getHeight() + 1, BufferedImage.TYPE_INT_RGB);

					Graphics2D g2d = image.createGraphics();
					
					if(!Launcher.getEditorGUI().getSplitPane().isOpaque()){
						Color bg = Launcher.getEditorGUI().getSplitPane().getBackground();
						bg = (bg.getAlpha() < 255) ? new Color(bg.getRed(), bg.getGreen(), bg.getBlue()) : bg;
						
						Color color = g2d.getColor();
						g2d.setColor(bg);
						g2d.fillRect(0, 0, Launcher.getEditorGUI().getSplitPane().getWidth(), Launcher.getEditorGUI().getSplitPane().getHeight());
						g2d.setColor(color);
					}
					
					Launcher.getEditorGUI().getSplitPane().paint(g2d);
					g2d.dispose();
					
					
					// Save As Dialog
					int returnVal = fc.showSaveDialog(this);
					
		            if (returnVal == JFileChooser.APPROVE_OPTION) {
		                file = fc.getSelectedFile();
		                
		                if(!file.getName().toLowerCase().endsWith(".png") && !file.getName().toLowerCase().endsWith(".jpg")){
		                	/**
			                 * On recupere le chemin d'acces du fichier pour lui ajouté
			                 * l'extension png par la fonction concat(string) qui concatène
			                 * des chaines de caractères
			                 **/
		                	String filePath = file.getPath().concat(".png");
		                	
			                /**
			                 * On instancie file avec son nouveau path (chemin d'accès)
			                 **/
			                file = new File(filePath);
		                } else {
		                	file = new File(file.getPath());
		                }
		                
		            } else {
		                // This is if we don't give a valid filename, save by default in application folder.
		            	file = new File(Constants.PNG_DEFAULT_FILEPATH);
		            }
	
					// Save the screenshot as a png
					ImageIO.write(image, "png", file);
	                
				} catch (Exception exception) {
					exception.printStackTrace();
				}
		}				
				
				
	
			if (event.getSource() == saveGraphItem) {
								
				/**
				* Fonction qui permet la sauvegarde des vertex et de leurs coordonées
				* pour ensuite etre reconstruit par la suite
				*/
				JFileChooser fc = new JFileChooser();
				File file = new File("default.eck");
				int returnVal = fc.showSaveDialog(fc);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
			            file = fc.getSelectedFile();
						EditingGraphMousePlugin.save = true;
			            if(!file.getName().toLowerCase().endsWith(".eck")){
			            	String filePath = file.getPath().concat(".eck");
			            	file = new File(filePath);
			            } else {
			            	file = new File(file.getPath());
			            }
			         
					
					try {
						// On instancie le flot d'ecriture
						FileWriter fw = new FileWriter(file);
						/*
						 * A cet emplacement on écrira tous les concepts
						 */
						fw.write("DebutConcept"+ System.getProperty("line.separator"));
						fw.write(CKModel.vecConceptSave.size() + System.getProperty("line.separator") + System.getProperty("line.separator"));
						for ( int i = 0; i < CKModel.vecConceptSave.size(); i++){
							fw.write(CKModel.vecConceptSave.elementAt(i).getIndex() + System.getProperty("line.separator"));
							fw.write(StringMethods.forHTML(CKModel.vecConceptSave.elementAt(i).getProposition()) +System.getProperty("line.separator"));
							fw.write(CKModel.vecConceptSave.elementAt(i).getPositionX() + System.getProperty("line.separator"));
							fw.write(CKModel.vecConceptSave.elementAt(i).getPositionY() + System.getProperty("line.separator") + System.getProperty("line.separator"));
						}
						
						/*
						 * A cet emplacement on écrira tous les Knowledges
						 */
						fw.write("DebutKnowledge"+ System.getProperty("line.separator"));
						fw.write(CKModel.vecKnowledgeSave.size() + System.getProperty("line.separator") + System.getProperty("line.separator"));
						for ( int i = 0; i < CKModel.vecKnowledgeSave.size(); i++){
							fw.write(CKModel.vecKnowledgeSave.elementAt(i).getIndex() + System.getProperty("line.separator"));
							fw.write(StringMethods.forHTML(CKModel.vecKnowledgeSave.elementAt(i).getProposition()) +System.getProperty("line.separator"));
							fw.write(CKModel.vecKnowledgeSave.elementAt(i).getPositionX() + System.getProperty("line.separator"));
							fw.write(CKModel.vecKnowledgeSave.elementAt(i).getPositionY() + System.getProperty("line.separator") + System.getProperty("line.separator"));
						}
						
						fw.write("DebutEdge"+ System.getProperty("line.separator"));
						fw.write(CKModel.vecEdgeSave.size() + System.getProperty("line.separator") + System.getProperty("line.separator"));
						for ( int i = 0; i < CKModel.vecEdgeSave.size(); i++){
							fw.write(CKModel.vecEdgeSave.elementAt(i).getIndex() + System.getProperty("line.separator"));
							fw.write(CKModel.vecEdgeSave.elementAt(i).getIndiceDebut() + System.getProperty("line.separator"));
							fw.write(CKModel.vecEdgeSave.elementAt(i).getIndiceFin() + System.getProperty("line.separator") + System.getProperty("line.separator"));
						}
						fw.close();
						
					} catch (IOException e) {

						e.printStackTrace();
					}	
				}
			}
			
			
			if (event.getSource() == loadGraphItem){
				JFileChooser fc = new JFileChooser();
				File file = new File("default.eck");
				Scanner scan;
				int dernierConcept = 0, dernierKnowledge = 0, dernierEdge = 0;
				
				int returnVal = fc.showOpenDialog(fc);
				if (returnVal == JFileChooser.APPROVE_OPTION) {
		            file = fc.getSelectedFile();
		            if(file.getName().toLowerCase().endsWith(".eck")){
		            	file = new File(file.getPath());
		            	/*
		            	 * On efface le graph précedent au chargement d'un nouveau
		            	 */
		            	Collection<Concept> cc = Launcher.getEditorGUI().getConceptPanel().getGraph().getVertices();
						Collection<Knowledge> ck = Launcher.getEditorGUI().getKnowledgePanel().getGraph().getVertices();
						while(cc.iterator().hasNext()){
							Launcher.getEditorGUI().getConceptPanel().getGraph().removeVertex(cc.iterator().next());
						}
						while(ck.iterator().hasNext()){
							Launcher.getEditorGUI().getKnowledgePanel().getGraph().removeVertex(ck.iterator().next());
						}
						
						/*
						 * On efface tout ce qui est contenu dans les vecteurs
						 */
						CKModel.vecConceptSave.removeAllElements();
						CKModel.vecKnowledgeSave.removeAllElements();
						CKModel.vecEdgeSave.removeAllElements();
						try {

							/*
			            	 * On recupere le pancelConcept pour pouvoir y faire la création des concepts
			            	 * une fois ceux ci récupérés
			            	 */
							final VisualizationViewer<Concept, Integer> vvC = Launcher.getEditorGUI().getConceptPanel().getVisuViewer();
							Layout<Concept, Integer> layoutC = vvC.getModel().getGraphLayout();
							Graph<Concept, Integer> graphC = vvC.getModel().getGraphLayout().getGraph();
							scan = new Scanner(new File(file.getPath()));
			
							String titre = scan.next();
							if (scan.hasNextLine() && titre.equals("DebutConcept")){
								/* Le premier entier en dessous de "DebutConcept" correspond au nombre de concepts que nous avons
								 * ce qui permet un traitement plus rapide étant donné que nous savons
								 * combien de fois boucler
								 */ 
								int cptC = scan.nextInt();
								for (int i=0; i<cptC; i++){
									Concept c = new Concept();
									c.setIndex(scan.nextInt());
									scan.nextLine();
									c.setProposition(StringMethods.forHTML(scan.nextLine()));
									int x = scan.nextInt();
									int y  = scan.nextInt();
									Point p = new Point(x,y);
									c.setPosition(p);
									c.setVecteurConceptSave();
									if (c.getIndex() > dernierConcept){
										dernierConcept = c.getIndex();
									}
									graphC.addVertex(c);
									layoutC.setLocation(c, vvC.getRenderContext().getMultiLayerTransformer().inverseTransform(c.getPosition()));
								}

								Launcher.getEditorGUI().getConceptPanel().getGraph().setVertexConceptCount(dernierConcept + 1);
								
							}
							/*
			            	 * On recupere le pancelKnowledge pour pouvoir y faire la création des knowledges
			            	 * une fois ceux ci récupérés
			            	 */
							final VisualizationViewer<Knowledge, Integer> vvK = Launcher.getEditorGUI().getKnowledgePanel().getVisuViewer();
							Layout<Knowledge, Integer> layoutK = vvK.getModel().getGraphLayout();
							Graph<Knowledge, Integer> graphK = vvK.getModel().getGraphLayout().getGraph();
							
							titre = scan.next();
							if(scan.hasNextLine() && titre.equals("DebutKnowledge")){
								/* Le premier entier en dessous de "DebutKnowledge" correspond au nombre de knowledges 
								 * que nous avons ce qui permet un traitement plus rapide étant donné que nous savons
								 * combien de fois boucler
								 */
								int cptK = scan.nextInt();
								for(int i=0; i<cptK; i++){
									Knowledge k = new Knowledge();
									k.setIndex(scan.nextInt());
									scan.nextLine();
									k.setProposition(StringMethods.forHTML(scan.nextLine()));
									int x = scan.nextInt();
									int y  = scan.nextInt();
									Point p = new Point(x,y);
									k.setPosition(p);
									k.setVecteurKnowledgeSave();
									if (k.getIndex() > dernierKnowledge){
										dernierKnowledge = k.getIndex();
									}
									graphK.addVertex(k);
									layoutK.setLocation(k, vvC.getRenderContext().getMultiLayerTransformer().inverseTransform(k.getPosition()));
								}
								Launcher.getEditorGUI().getKnowledgePanel().getGraph().setvertexKnowledgeCount(dernierKnowledge + 1);
							}
							
							
							
							titre = scan.next();
							if(scan.hasNextLine() && titre.equals("DebutEdge")){
								int cptE = scan.nextInt();
								
								for (int i=0; i<cptE; i++){
									Edge e = new Edge();
									e.setIndex(scan.nextInt());
									e.setIndiceDebut(scan.nextInt());
									e.setIndiceFin(scan.nextInt());
									e.setVecEdgeSave();
									if ( e.getIndex() > dernierEdge){
										dernierEdge = e.getIndex();
									}
									Concept debut = new Concept();
									Concept fin = new Concept();
									for (int j=0; j<CKModel.vecConceptSave.size(); j++){
										if(CKModel.vecConceptSave.elementAt(j).getIndex() == e.getIndiceDebut()){
											debut = CKModel.vecConceptSave.elementAt(j);
										}
										if (CKModel.vecConceptSave.elementAt(j).getIndex() == e.getIndiceFin()){
											fin = CKModel.vecConceptSave.elementAt(j);
										}
									}
									EdgeType edgeIsDirected = EdgeType.UNDIRECTED;
									graphC.addEdge(e.getIndex(), debut, fin, edgeIsDirected);
								}
								Launcher.getEditorGUI().getConceptPanel().getGraph().setEdgeCount(dernierEdge + 1);
							}
							scan.close();
						} catch (FileNotFoundException e) {
							e.printStackTrace();
						}
		            	
		            } else {
		            	JOptionPane.showMessageDialog(this, "Ce n'est pas un fichier de type 'nom_de_fichier.eck'",
		            			"ERREUR",JOptionPane.ERROR_MESSAGE);
		            }
				}


			}
			if (event.getSource() == createGraphCK){
				
				frameCreateGraphCK.remove(panelActionHelp);
				frameCreateGraphCK.add(panelCreateGraphCK);
				frameCreateGraphCK.repaint();
				frameCreateGraphCK.setVisible(true);
				
			}
			if (event.getSource() == actionHelp){
				

				frameCreateGraphCK.remove(panelCreateGraphCK);
				frameCreateGraphCK.add(panelActionHelp);
				frameCreateGraphCK.repaint();
				frameCreateGraphCK.setVisible(true);
				
			}
	
				try {
					Launcher.getLogger().SaveToFile("History.txt");
				} catch (FileNotFoundException e) {

					e.printStackTrace();
				} catch (IOException e) {
					
					e.printStackTrace();
				}
			}
}
